// 全局变量
let nodes = [];
let connections = [];
let selectedNode = null;
let draggingNode = null;
let draggingPort = null;
let tempConnection = null;
let offset = { x: 0, y: 0 };
let scale = 1;
let pan = { x: 0, y: 0 };

// 节点类型配置
const nodeTypes = {
    math: {
        inputs: ['Number A', 'Number B'],
        outputs: ['Result'],
        properties: {
            operation: 'add'
        }
    },
    logic: {
        inputs: ['Value A', 'Value B'],
        outputs: ['Result'],
        properties: {
            operation: 'and'
        }
    },
    input: {
        inputs: [],
        outputs: ['Value'],
        properties: {
            defaultValue: '0'
        }
    },
    output: {
        inputs: ['Value'],
        outputs: [],
        properties: {
            label: 'Output'
        }
    }
};

// 初始化
document.addEventListener('DOMContentLoaded', function() {
    const canvas = document.getElementById('canvas');
    
    // 画布事件监听
    canvas.addEventListener('mousemove', handleMouseMove);
    canvas.addEventListener('mouseup', handleMouseUp);
    canvas.addEventListener('wheel', handleWheel);
    
    // 防止右键菜单
    canvas.addEventListener('contextmenu', e => e.preventDefault());
});

// 创建新节点
function addNode(type, title) {
    const nodeConfig = nodeTypes[type];
    const node = {
        id: 'node_' + Date.now(),
        type: type,
        title: title,
        x: 100,
        y: 100,
        inputs: nodeConfig.inputs,
        outputs: nodeConfig.outputs,
        properties: { ...nodeConfig.properties }
    };
    
    createNodeElement(node);
    nodes.push(node);
}

// 创建节点DOM元素
function createNodeElement(node) {
    const canvas = document.getElementById('canvas');
    const nodeElement = document.createElement('div');
    
    nodeElement.className = `node node-type-${node.type}`;
    nodeElement.id = node.id;
    nodeElement.style.left = node.x + 'px';
    nodeElement.style.top = node.y + 'px';
    
    // 节点内容
    nodeElement.innerHTML = `
        <div class="node-header">${node.title}</div>
        <div class="node-content">
            <div class="node-ports">
                ${node.inputs.map((input, index) => `
                    <div class="port port-input" data-port="input-${index}">
                        <div class="port-dot" data-port-type="input" data-port-index="${index}"></div>
                        <span class="port-label">${input}</span>
                    </div>
                `).join('')}
                ${node.outputs.map((output, index) => `
                    <div class="port port-output" data-port="output-${index}">
                        <span class="port-label">${output}</span>
                        <div class="port-dot" data-port-type="output" data-port-index="${index}"></div>
                    </div>
                `).join('')}
            </div>
        </div>
    `;
    
    // 事件监听
    nodeElement.querySelector('.node-header').addEventListener('mousedown', handleNodeMouseDown);
    
    nodeElement.querySelectorAll('.port-dot').forEach(port => {
        port.addEventListener('mousedown', handlePortMouseDown);
    });
    
    nodeElement.addEventListener('click', (e) => {
        if (!e.target.classList.contains('port-dot')) {
            selectNode(node);
        }
    });
    
    canvas.appendChild(nodeElement);
}

// 处理节点拖动开始
function handleNodeMouseDown(e) {
    const nodeElement = e.target.closest('.node');
    if (!nodeElement) return;
    
    draggingNode = nodeElement;
    const rect = nodeElement.getBoundingClientRect();
    offset.x = e.clientX - rect.left;
    offset.y = e.clientY - rect.top;
    
    // 选中当前节点
    selectNode(nodes.find(n => n.id === nodeElement.id));
}

// 处理端口拖动开始
function handlePortMouseDown(e) {
    e.stopPropagation();
    draggingPort = e.target;
    
    // 创建临时连接线
    tempConnection = createConnection(
        draggingPort.closest('.node').id,
        draggingPort.getAttribute('data-port-type'),
        { x: e.clientX, y: e.clientY }
    );
}

// 处理鼠标移动
function handleMouseMove(e) {
    if (draggingNode) {
        const x = e.clientX - offset.x;
        const y = e.clientY - offset.y;
        
        draggingNode.style.left = x + 'px';
        draggingNode.style.top = y + 'px';
        
        // 更新节点位置
        const node = nodes.find(n => n.id === draggingNode.id);
        if (node) {
            node.x = x;
            node.y = y;
        }
        
        // 更新连接线
        updateConnections();
    }
    
    if (draggingPort) {
        updateTempConnection(e.clientX, e.clientY);
    }
}

// 处理鼠标释放
function handleMouseUp(e) {
    if (draggingPort) {
        const targetElement = document.elementFromPoint(e.clientX, e.clientY);
        
        if (targetElement && targetElement.classList.contains('port-dot')) {
            const sourcePort = draggingPort;
            const targetPort = targetElement;
            
            // 检查是否可以建立连接
            if (canConnect(sourcePort, targetPort)) {
                createFinalConnection(sourcePort, targetPort);
            }
        }
        
        // 清除临时连接线
        if (tempConnection) {
            tempConnection.remove();
            tempConnection = null;
        }
        
        draggingPort = null;
    }
    
    draggingNode = null;
}

// 处理滚轮缩放
function handleWheel(e) {
    e.preventDefault();
    
    const delta = e.deltaY;
    const scaleChange = delta > 0 ? 0.95 : 1.05;
    
    scale = Math.min(Math.max(0.5, scale * scaleChange), 2);
    
    const canvas = document.getElementById('canvas');
    canvas.style.transform = `scale(${scale})`;
}

// 创建连接线
function createConnection(nodeId, portType, endPoint) {
    const connection = document.createElement('div');
    connection.className = 'connection';
    
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.style.position = 'absolute';
    svg.style.width = '100%';
    svg.style.height = '100%';
    svg.style.overflow = 'visible';
    
    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    svg.appendChild(path);
    connection.appendChild(svg);
    
    document.getElementById('canvas').appendChild(connection);
    
    return connection;
}

// 更新临时连接线
function updateTempConnection(x, y) {
    if (!tempConnection || !draggingPort) return;
    
    const sourceRect = draggingPort.getBoundingClientRect();
    const canvasRect = document.getElementById('canvas').getBoundingClientRect();
    
    const startX = sourceRect.left + sourceRect.width/2 - canvasRect.left;
    const startY = sourceRect.top + sourceRect.height/2 - canvasRect.top;
    const endX = x - canvasRect.left;
    const endY = y - canvasRect.top;
    
    const path = tempConnection.querySelector('path');
    const controlPointOffset = Math.abs(endX - startX) * 0.5;
    
    path.setAttribute('d', `M ${startX} ${startY} C ${startX + controlPointOffset} ${startY}, ${endX - controlPointOffset} ${endY}, ${endX} ${endY}`);
}

// 检查是否可以建立连接
function canConnect(sourcePort, targetPort) {
    if (!sourcePort || !targetPort) return false;
    if (sourcePort === targetPort) return false;
    if (sourcePort.closest('.node') === targetPort.closest('.node')) return false;
    
    const sourceType = sourcePort.getAttribute('data-port-type');
    const targetType = targetPort.getAttribute('data-port-type');
    
    return (sourceType === 'output' && targetType === 'input') ||
           (sourceType === 'input' && targetType === 'output');
}

// 创建最终连接
function createFinalConnection(sourcePort, targetPort) {
    const connection = {
        id: 'conn_' + Date.now(),
        sourceNode: sourcePort.closest('.node').id,
        targetNode: targetPort.closest('.node').id,
        sourcePort: sourcePort.getAttribute('data-port-index'),
        targetPort: targetPort.getAttribute('data-port-index'),
        sourceType: sourcePort.getAttribute('data-port-type'),
        targetType: targetPort.getAttribute('data-port-type')
    };
    
    // 确保连接从输出到输入
    if (connection.sourceType === 'input') {
        [connection.sourceNode, connection.targetNode] = [connection.targetNode, connection.sourceNode];
        [connection.sourcePort, connection.targetPort] = [connection.targetPort, connection.sourcePort];
        [connection.sourceType, connection.targetType] = [connection.targetType, connection.sourceType];
    }
    
    connections.push(connection);
    updateConnections();
}

// 更新所有连接线
function updateConnections() {
    // 移除所有现有的连接线
    document.querySelectorAll('.connection').forEach(conn => {
        if (conn !== tempConnection) {
            conn.remove();
        }
    });
    
    // 重新绘制所有连接
    connections.forEach(conn => {
        const sourceNode = document.getElementById(conn.sourceNode);
        const targetNode = document.getElementById(conn.targetNode);
        
        if (!sourceNode || !targetNode) return;
        
        const sourcePort = sourceNode.querySelector(`[data-port-type="output"][data-port-index="${conn.sourcePort}"]`);
        const targetPort = targetNode.querySelector(`[data-port-type="input"][data-port-index="${conn.targetPort}"]`);
        
        if (!sourcePort || !targetPort) return;
        
        const connection = createConnection();
        const sourceRect = sourcePort.getBoundingClientRect();
        const targetRect = targetPort.getBoundingClientRect();
        const canvasRect = document.getElementById('canvas').getBoundingClientRect();
        
        const startX = sourceRect.left + sourceRect.width/2 - canvasRect.left;
        const startY = sourceRect.top + sourceRect.height/2 - canvasRect.top;
        const endX = targetRect.left + targetRect.width/2 - canvasRect.left;
        const endY = targetRect.top + targetRect.height/2 - canvasRect.top;
        
        const path = connection.querySelector('path');
        const controlPointOffset = Math.abs(endX - startX) * 0.5;
        
        path.setAttribute('d', `M ${startX} ${startY} C ${startX + controlPointOffset} ${startY}, ${endX - controlPointOffset} ${endY}, ${endX} ${endY}`);
    });
}

// 选择节点
function selectNode(node) {
    // 取消之前选中的节点
    document.querySelectorAll('.node').forEach(el => el.classList.remove('selected'));
    
    selectedNode = node;
    
    if (node) {
        const element = document.getElementById(node.id);
        if (element) {
            element.classList.add('selected');
        }
        
        updateProperties(node);
    }
}

// 更新属性面板
function updateProperties(node) {
    const propertiesPanel = document.getElementById('nodeProperties');
    let html = `
        <div class="property-item">
            <label>Node Title</label>
            <input type="text" value="${node.title}" onchange="updateNodeProperty('title', this.value)">
        </div>
    `;
    
    // 根据节点类型添加特定属性
    switch(node.type) {
        case 'math':
            html += `
                <div class="property-item">
                    <label>Operation</label>
                    <select onchange="updateNodeProperty('operation', this.value)">
                        <option value="add" ${node.properties.operation === 'add' ? 'selected' : ''}>Add</option>
                        <option value="subtract" ${node.properties.operation === 'subtract' ? 'selected' : ''}>Subtract</option>
                        <option value="multiply" ${node.properties.operation === 'multiply' ? 'selected' : ''}>Multiply</option>
                        <option value="divide" ${node.properties.operation === 'divide' ? 'selected' : ''}>Divide</option>
                    </select>
                </div>
            `;
            break;
        case 'logic':
            html += `
                <div class="property-item">
                    <label>Operation</label>
                    <select onchange="updateNodeProperty('operation', this.value)">
                        <option value="and" ${node.properties.operation === 'and' ? 'selected' : ''}>AND</option>
                        <option value="or" ${node.properties.operation === 'or' ? 'selected' : ''}>OR</option>
                        <option value="not" ${node.properties.operation === 'not' ? 'selected' : ''}>NOT</option>
                    </select>
                </div>
            `;
            break;
        case 'input':
            html += `
                <div class="property-item">
                    <label>Default Value</label>
                    <input type="text" value="${node.properties.defaultValue}" onchange="updateNodeProperty('defaultValue', this.value)">
                </div>
            `;
            break;
        case 'output':
            html += `
                <div class="property-item">
                    <label>Output Label</label>
                    <input type="text" value="${node.properties.label}" onchange="updateNodeProperty('label', this.value)">
                </div>
            `;
            break;
    }
    
    propertiesPanel.innerHTML = html;
}
      

// 更新节点属性
function updateNodeProperty(property, value) {
    if (!selectedNode) return;
    
    if (property === 'title') {
        selectedNode.title = value;
        const element = document.getElementById(selectedNode.id);
        if (element) {
            element.querySelector('.node-header').textContent = value;
        }
    } else {
        selectedNode.properties[property] = value;
    }
}

// 保存流程
function saveFlow() {
    const data = {
        nodes: nodes,
        connections: connections
    };
    
    const blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'});
    const url = URL.createObjectURL(blob);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = 'flow.json';
    a.click();
    
    URL.revokeObjectURL(url);
}

// 加载流程
function loadFlow() {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    
    input.onchange = function(e) {
        const file = e.target.files[0];
        const reader = new FileReader();
        
        reader.onload = function(e) {
            const data = JSON.parse(e.target.result);
            
            // 清除现有内容
            clearCanvas();
            
            // 加载节点
            data.nodes.forEach(node => {
                nodes.push(node);
                createNodeElement(node);
            });
            
            // 加载连接
            connections = data.connections;
            updateConnections();
        };
        
        reader.readAsText(file);
    };
    
    input.click();
}

// 清除画布
function clearCanvas() {
    const canvas = document.getElementById('canvas');
    while (canvas.firstChild) {
        canvas.removeChild(canvas.firstChild);
    }
    
    nodes = [];
    connections = [];
    selectedNode = null;
    
    // 清除属性面板
    document.getElementById('nodeProperties').innerHTML = '<p style="color: #666;">Select a node to edit properties</p>';
}

// 计算节点值
function calculateNodeValue(node) {
    switch(node.type) {
        case 'math':
            const inputA = getInputValue(node, 0) || 0;
            const inputB = getInputValue(node, 1) || 0;
            
            switch(node.properties.operation) {
                case 'add': return inputA + inputB;
                case 'subtract': return inputA - inputB;
                case 'multiply': return inputA * inputB;
                case 'divide': return inputB !== 0 ? inputA / inputB : 'Error: Divide by zero';
            }
            break;
            
        case 'logic':
            const valueA = getInputValue(node, 0);
            const valueB = getInputValue(node, 1);
            
            switch(node.properties.operation) {
                case 'and': return valueA && valueB;
                case 'or': return valueA || valueB;
                case 'not': return !valueA;
            }
            break;
            
        case 'input':
            return parseFloat(node.properties.defaultValue) || 0;
            
        case 'output':
            return getInputValue(node, 0);
    }
    
    return null;
}

// 获取输入值
function getInputValue(node, inputIndex) {
    const connection = connections.find(conn => 
        conn.targetNode === node.id && 
        parseInt(conn.targetPort) === inputIndex
    );
    
    if (!connection) return null;
    
    const sourceNode = nodes.find(n => n.id === connection.sourceNode);
    return sourceNode ? calculateNodeValue(sourceNode) : null;
}

// 执行流程
function executeFlow() {
    // 找到所有输出节点
    const outputNodes = nodes.filter(node => node.type === 'output');
    
    // 计算每个输出节点的值
    outputNodes.forEach(node => {
        const value = calculateNodeValue(node);
        console.log(`Output ${node.properties.label}: ${value}`);
    });
}